import cx_Oracle
from .db_api import DbApi


class OraclePlugin(DbApi):
    _test_connection_sql = "select 1 from dual"
    conn_type = 'oracle'
    conn_name_attr = "conn_id"

    def __init__(self, *args, **kwargs) -> None:
        super().__init__(*args, **kwargs)
        self.schema = kwargs.pop("schema", None)
        self.connection = kwargs.pop("connection", None)

    def get_conn(self):
        conn = self.connection or self.get_connection(getattr(self, self.conn_name_attr))
        conn_config = {'user': conn.login, 'password': conn.password}
        schema = conn.schema
        if conn.extra_dejson.get('charset', False):
            conn_config["encoding"] = conn.extra_dejson["charset"]
            if conn_config["encoding"].lower() in ('utf8', 'utf-8'):
                conn_config["use_unicode"] = True
        sid = conn.extra_dejson.get('sid')
        service_name = conn.extra_dejson.get('service_name')

        if conn.host and sid and not service_name:
            conn_config['dsn'] = cx_Oracle.makedsn(conn.host, conn.port, sid)
        elif conn.host and service_name and not sid:
            conn_config['dsn'] = cx_Oracle.makedsn(conn.host, conn.port, service_name=service_name)
        else:
            dsn = conn.extra_dejson.get('dsn')
            if dsn is None:
                dsn = conn.host
                if conn.port is not None:
                    dsn += ":" + str(conn.port)
                if service_name:
                    dsn += "/" + service_name
                elif conn.schema:
                    dsn += "/" + conn.schema
            conn_config['dsn'] = dsn

        mode = conn.extra_dejson.get('mode', '').lower()
        if mode == 'sysdba':
            conn_config['mode'] = cx_Oracle.SYSDBA
        elif mode == 'sysasm':
            conn_config['mode'] = cx_Oracle.SYSASM
        elif mode == 'sysoper':
            conn_config['mode'] = cx_Oracle.SYSOPER
        elif mode == 'sysbkp':
            conn_config['mode'] = cx_Oracle.SYSBKP
        elif mode == 'sysdgd':
            conn_config['mode'] = cx_Oracle.SYSDGD
        elif mode == 'syskmt':
            conn_config['mode'] = cx_Oracle.SYSKMT
        elif mode == 'sysrac':
            conn_config['mode'] = cx_Oracle.SYSRAC
        else:
            conn_config['mode'] = cx_Oracle.DEFAULT_AUTH

        try:
            conn = cx_Oracle.connect(**conn_config)
        except Exception as e:
            print("连接oracle异常，conn_id:%s, dsn:%s, mode:%s" %(self.conn_id, conn_config['dsn'], conn_config['mode']))
            raise e

        if schema and service_name:
            conn.current_schema = schema

        return conn

    def get_records(self, sql, parameters=None, cursor=None):
        """
        Executes the sql and returns a set of records.

        :param sql: the sql statement to be executed (str) or a list of
            sql statements to execute
        :param parameters: The parameters to render the SQL query with.
        """
        raw_records = super(OraclePlugin, self).get_records(sql, parameters, cursor)
        cols_desc = self.get_cols_desc(sql)

        return raw_records
